#![cfg_attr(
    // 条件编译配置：当满足所有条件时应用此属性
    all(not(debug_assertions), target_os = "windows"),
    // 条件：非调试模式且目标操作系统为Windows
    windows_subsystem = "windows"
    // 设置为Windows子系统（隐藏控制台窗口）
)]
// 条件编译属性：在Windows非调试模式下，设置为Windows子系统（隐藏控制台窗口）
// 这个属性告诉Rust编译器：
// 当条件满足时：将程序编译为Windows GUI应用程序
// 当条件不满足时：将程序编译为控制台应用程序（默认）

use librustdesk::*;
// 导入librustdesk库的所有公共接口

#[cfg(any(target_os = "android", target_os = "ios", feature = "flutter"))]
// 条件编译：仅在Android、iOS平台或启用flutter特性时编译此函数
fn main() {
    if !common::global_init() {
        // 执行全局初始化，如果失败则退出程序
        eprintln!("Global initialization failed.");
        // 向标准错误输出打印错误信息
        return;
        // 提前返回，终止程序执行
    }
    common::test_rendezvous_server();
    // 测试会合服务器的连接性
    common::test_nat_type();
    // 测试NAT类型，用于P2P连接
    common::global_clean();
    // 执行全局清理操作，释放资源
}

#[cfg(not(any(
    target_os = "android",
    target_os = "ios",
    feature = "cli",
    feature = "flutter"
)))]
// 条件编译：仅在非Android、非iOS、非CLI、非Flutter的平台上编译此函数（主要是桌面GUI模式）
fn main() {
    if !common::global_init() {
        // 执行全局初始化，如果失败则直接返回
        return;
        // 提前返回，终止程序执行
    }
    #[cfg(all(windows, not(feature = "inline")))]
    // 条件编译：仅在Windows平台且未启用inline特性时编译
    unsafe {
        // 不安全代码块：调用Windows API
        winapi::um::shellscalingapi::SetProcessDpiAwareness(2);
        // 设置进程DPI感知级别为2（Per-Monitor DPI Aware V2），用于高DPI显示适配
    }
    if let Some(args) = crate::core_main::core_main().as_mut() {
        // 调用核心主函数获取命令行参数，如果返回Some则继续
        ui::start(args);
        // 启动用户界面，传入解析后的参数
    }
    common::global_clean();
    // 执行全局清理操作
}

#[cfg(feature = "cli")]
// 条件编译：仅在启用CLI特性时编译此函数（命令行模式）
fn main() {
    if !common::global_init() {
        // 执行全局初始化，失败则退出
        return;
        // 提前返回，终止程序执行
    }
    use clap::App;
    // 导入clap命令行参数解析库的App结构
    use hbb_common::log;
    // 导入日志模块
    let args = format!(
        "-p, --port-forward=[PORT-FORWARD-OPTIONS] 'Format: remote-id:local-port:remote-port[:remote-host]'
        -c, --connect=[REMOTE_ID] 'test only'
        -k, --key=[KEY] ''
       -s, --server=[] 'Start server'",
    );
    // 定义命令行参数格式字符串：
    // -p: 端口转发选项，格式为 远程ID:本地端口:远程端口[:远程主机]
    // -c: 连接到远程ID（仅用于测试）
    // -k: 认证密钥
    // -s: 启动服务器
    let matches = App::new("rustdesk")
        // 创建名为"rustdesk"的命令行应用
        .version(crate::VERSION)
        // 设置版本号
        .author("Purslane Ltd<info@rustdesk.com>")
        // 设置作者信息
        .about("RustDesk command line tool")
        // 设置应用描述
        .args_from_usage(&args)
        // 从使用说明字符串解析参数定义
        .get_matches();
        // 获取实际的命令行参数匹配结果
    use hbb_common::{config::LocalConfig, env_logger::*};
    // 导入本地配置和环境日志模块
    init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info"));
    // 从环境变量初始化日志系统，默认级别为info
    if let Some(p) = matches.value_of("port-forward") {
        // 如果用户指定了端口转发参数
        let options: Vec<String> = p.split(":").map(|x| x.to_owned()).collect();
        // 按冒号分割端口转发选项字符串
        if options.len() < 3 {
            // 检查参数数量是否足够（至少需要3个：远程ID、本地端口、远程端口）
            log::error!("Wrong port-forward options");
            // 记录错误日志
            return;
            // 提前返回，终止程序执行
        }
        let mut port = 0;
        // 初始化本地端口变量
        if let Ok(v) = options[1].parse::<i32>() {
            // 尝试解析第二个参数为整数（本地端口）
            port = v;
        } else {
            log::error!("Wrong local-port");
            // 解析失败，记录错误
            return;
            // 提前返回，终止程序执行
        }
        let mut remote_port = 0;
        // 初始化远程端口变量
        if let Ok(v) = options[2].parse::<i32>() {
            // 尝试解析第三个参数为整数（远程端口）
            remote_port = v;
        } else {
            log::error!("Wrong remote-port");
            // 解析失败，记录错误
            return;
            // 提前返回，终止程序执行
        }
        let mut remote_host = "localhost".to_owned();
        // 默认远程主机为localhost
        if options.len() > 3 {
            // 如果提供了第四个参数（远程主机）
            remote_host = options[3].clone();
            // 使用指定的远程主机
        }
        common::test_rendezvous_server();
        // 测试会合服务器
        common::test_nat_type();
        // 测试NAT类型
        let key = matches.value_of("key").unwrap_or("").to_owned();
        // 获取认证密钥，如果未提供则使用空字符串
        let token = LocalConfig::get_option("access_token");
        // 从本地配置获取访问令牌
        cli::start_one_port_forward(
            options[0].clone(),
            port,
            remote_host,
            remote_port,
            key,
            token,
        );
        // 启动端口转发功能，传入所有必要参数
    } else if let Some(p) = matches.value_of("connect") {
        // 如果用户指定了连接参数
        common::test_rendezvous_server();
        // 测试会合服务器
        common::test_nat_type();
        // 测试NAT类型
        let key = matches.value_of("key").unwrap_or("").to_owned();
        // 获取认证密钥
        let token = LocalConfig::get_option("access_token");
        // 获取访问令牌
        cli::connect_test(p, key, token);
        // 执行连接测试
    } else if let Some(p) = matches.value_of("server") {
        // 如果用户指定了服务器参数
        log::info!("id={}", hbb_common::config::Config::get_id());
        // 记录当前设备的ID信息
        crate::start_server(true, false);
        // 启动服务器，参数为(true=显示界面, false=不是无服务器模式)
    }
    common::global_clean();
    // 执行全局清理操作
}
